home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 1
/
SPACE - Library 1 - Volume 1.iso
/
program
/
245
/
gfagrphc.doc
< prev
next >
Wrap
Text File
|
1988-02-07
|
60KB
|
2,304 lines
Figures and programs included in this Sample Chapter:
Figures:
Figure 3-1. Organization of Screen Memory for Monochrome Display.
Figure 3-2 Organization of Color Screen Memory
Figure 3-3. Cartesian Coordinate System
Figure 3-4 Polar Coordinate System
Figure 3-5. Raster Coordinate System
Figure 3-6. Normalized Device Coordinate (NDC) System
Figure 3-7. The Mandelbrot Primitive
Figure 3-8. Mandelbrot Figure
Figure 3-9. ANother Segment of the Mandelbrot Boundary.
Programs:
Program 3-1. LINEDRAW.PRG
Program 3-2 STRING.BAS
Program 3-3. KALEIDO.BAS
Program 3-4. DRAGON.BAS
Program 3-5. MANDELBROT.BAS
Program 3-6. NEOWRITE.BAS
Program 3-7. NEOLOAD.BAS
Chapter 3
ST Graphics
During the late 1950s and early 1960s, the Massachusetts Institute
of Technoloy (MIT) was the center of the computer world, an
academic community actively involved in the research and
construction of supercomputer systems.
In 1963, Ivan Sutherland, a young graduate student working on
his doctoral dissertation at MIT, could often be seen working far
into the night at the terminal of a giant mainframe computer. He
wasn't alone in his labors. Other students doing research on
computers had to use the late-night hours, when the mainframes
weren't being used for other purposes, for exploring the limits of
this fledgling science of computers; the technology for
microcomputers had not even been developed.
Sutherland wrote and rewrote his lines of code. After much
revision, he was finally successful. The monitor display cleared,
and a green line appeared: The first computer graphic, a straight
line, had been produced by the giant mainframe. Not much by
today's standards, but this occasion marked the beginning of a
whole new art form --computer graphics.
This single straight line evolved into the Sketchpad line-
drawing program. Sutherland's early drawing program allowed the
user to point at the screen with a light pen to sketch objects.
This simple system was the predecessor of today's complex
computer-assisted drawing (CAD) programs.
A lot had to happen to computers, however, before
sophisticated computer graphics could become a reality. For a
while computers remained the expensive tools of government and
universities. In 1965, IBM introduced the first mass-produced
cathode ray tube (CRT), but the price was more than $100,000 for
the CRT only. This price tag made entry into computer graphics
practically impossible for all but a few specialized users. In
1968, Tektronics introduced the storage-tube CRT, which displayed
a drawing by retaining the image until the user replaced it. This
type of display eliminated the need for costly memory and hardware
to store and display the image, but the selling price of $15,000
still placed the CRT far beyond the means of most users.
It wasn't until the late 1970s and early 1980s that the
microcomputer industry exploded, and computer wars brought the
price and power of the personal computer within the reach of the
middle-income person.
Soon, powerful graphics programs such as DEGAS and NEOchrome
had introduced many people to this new art form, and some even
discovered hidden talents. And now that computer art has become
accessible to so many people, those people want to make the best
possible use of its potential.
In this chapter, we'll take you beyond DEGAS and NEOchrome,
showing you how to develop and use the powerful graphics routines
built into the ST. Previously, exploitation of these features was
rather difficult. Most programmers resorted to C or assembly
language programming when sophisticated graphics were required.
GFA BASIC delivers the power to fully utilize the graphics
potential of your ST. Stunning graphics are easily obtained using
the GFA BASIC interpreter, while the GFA BASIC compiler allows you
to develop arcade-quality games in BASIC, then execute the
programs from the GEM Desktop with your program running at speeds
rivaling those of assembly language.
Computer Graphics
Computer graphics is a generic term which refers to any image
created with a computer. This covers a wide range, from a simple
line on a monitor, to intricate pictures developed with drawing
programs, and more. Some computer scientists, for instance, are
using computers to control lasers which produce holographic
images. Perhaps the scene from Star Wars where C3PO and Chew-baka
are playing a chesslike game with holographic images isn't even
that far-fetched.
The motion picture industry, in recent years, has used
computer graphics extensively. The transformation of the Genesis
planet in Star Trek II, The Wrath of Khan, was an effect produced
with fractal graphics --one of the most fascinating areas of
computer graphics (and one which we'll explore later in this
chapter). Disney Studios merged real action with computer-
generated graphics in the movie TRON. The Last Starfighter has 25
minutes of spectacular computer imagery, with each frame requiring
dozens of algorithms and hundreds of intricate designs. In fact,
such movies have contributed to the birth of a new industry
devoted to enhancing computer-generated graphics technology, with
one of the leaders in this new industry being Lucasfilm, a pioneer
in special effects since the Star Wars trilogy.
Although holographic imaging and Hollywood-type special
effects are beyond the scope of this book, it will show you a
fascinating world open to those who know the power of the ST.
Graphics Capabilities
Good graphics require a minimum of a high-resolution display and a
large number of colors to work with. Some rumors are beginning to
circulate about computers for homes and businesses with monitors
capable of displaying up to one million --1000 X 1000 --pixels.
Currently only dedicated graphics workstations, such as the Sun or
the Cray II, offer such capabilities, and both of these are priced
far beyond the home enthusiast's budget. Although the ST doesn't
have the capabilities of a dedicated graphics workstation, it is
capable of displaying up to 256,000 pixels, for a fraction of the
cost. Plus, the palette of 512 colors makes it ideal for producing
colorful, exciting displays.
In order to program graphics on the ST, it's necessary to
understand a little about the way the screen is displayed. On the
monochrome screen, each pixel (picture element) is represented by
a single bit of memory. Each bit will be either a 0 or a 1,
indicating whether each pixel is off or on, respectively. Screen
memory is organized so that the first byte represents the 8
pixels, or dots, at the top left corner of the screen. Each
succeeding byte represents the next 8 pixels in succession. Each
⇧screen line consists of 640 pixels, so the first 80 bytes (80
times 8) represent the top row of the screen. Since there are 400
lines of pixels vertically on the screen, a total of 256,000 bits
are used to represent the monochrome screen. This means that
32,000 bytes of screen memory are used to store the display.
Binary Decimal
00 0
01 1
10 2
11 3
Figure 3-1 Organization of Screen Memory for Monochrome Display.
Color screen memory is organized in much the same way as
monochrome screen memory, but instead of single bits representing
single pixels, groups of bits are used to represent each pixel. In
medium resolution, a pixel may be one of four colors. Two bits are
used to create the four possible colors:
The first byte of screen memory represents the first four
pixels at the upper left corner of the screen. The two high-order
bits specify the color in the first pixel, the next two bits
represent the color in the second pixel, and so on. There are 640
pixels per row; each row requires 160 bytes of memory. Since there
are only 200 vertical rows of pixels, only 32,000 bytes of memory
are necessary to store a screen.
In low resolution, a pixel can be one of 16 colors, so four
bits are required to represent a single pixel.
0000 = 0 1000 = 8
0001 = 1 1001 = 9
0010 = 2 1010 = 10
0011 = 3 1011 = 11
0100 = 4 1100 = 12
0101 = 5 1101 = 13
0110 = 6 1110 = 14
0111 = 7 1111 = 15
Each byte describes the color of only 2 pixels. But again,
since there are only 320 pixels per line, and 200 vertical lines,
only 32,000 bytes are required to represent a full screen.
Figure 3-2 Organization of Color Screen Memory
As mentioned previously, the ST is capable of displaying 512
colors, but only 16 colors may be displayed at one time (in low
resolution). Each value stored in color memory corresponds to a
hardware color register.
In GFA BASIC, the command COLOR defines the color to be used
by a graphics command. If you do not specify a color before a
graphics command, either the default color or the color last used
is selected. Usually, the default color is color 1, which has a
default value of black, 0.
Graphics Programming Techniques
Entire books have been written about the various phases of
computer graphics. Each section of this chapter could be dealt
with in much greater detail. Instead, we're going to introduce
you, quickly and painlessly, to graphics techniques, point you in
the right direction, and then leave you to the excitement of
discovery as you explore this world with your staunch ally, GFA
BASIC.
As with any voyage, some preliminary attention to detail must
be undertaken. After all, to use the graphics commands, you must
at least be able to tell the computer where you want the object
you're drawing to appear.
There are several coordinate systems in use, but the two most
common are the Cartesian coordinate system and the polar
coordinate system.
In the Cartesian coordinate system, the two-dimensional plane
is assigned two axes: the horizontal axis, usually labeled x, and
the vertical axis, Çusually labeled y. By convention, the positive
direction of the x-axis is to the right, but the positive
direction of the y-axis can be either up or down, depending on the
application. In geometry and most other mathematical applications,
the positive direction of the y-axis is up, but on most computer
systems, the positive direction is down. Points in the plane are
represented by ordered pairs (x,y), where x is the distance of the
point from the y-axis and y is the distance of the point from the
x-axis. The point (0,0) is called the origin because it is the
point where the x and y axes intersect, the point from which all
other points in the plane are located.
The location of the origin is another disputed aspect of the
Cartesian coordinate system. In geometry, the origin is
traditionally located in the lower left corner of the display with
the positive x and y axes extending toward the right and top of
the display, respectively. However, on most computers, the origin
is located in the upper left corner of the screen, because of the
way the monitor draws the display. Another possible location for
the origin is the center of the display. This orientation makes it
easy to graph both negative as well as positive values --
something the other two systems ignore. Either of these locations
is equally valid, and conversion from one orientation to the other
is simple, so the choice of which system to use is usually left up
to the user.
Figure 3-3. Cartesian Coordinate System
Figure 3-4 Polar Coordinate System
The Cartesian coordinate system cooresponds closely with the
real world, which makes it ideal for most applications, but in
situations where rotation is necessary, the Cartesian coordinate
system is difficult to use. Two systems of referencing are in
common use with computers: the normalized device coordinate (NDC)
system, and the raster coordinate (RC) system
. The NDC system addresses the graphics display independent of the
device's display size, while the RC system addresses the device in
actual display units. The RC system is the system used on most
microcomputers. With this system, the screen is divided into rows
and columns of dots, or pixels. The pixels in the top row have a
vertical, or y, coordinate of 0. The y coordinate increases as you
move toward the bottom of the screen. The bottom row of the screen
has a y coordinate value of 199 on a color system and 399 on a
monochrome system. The leftmost column of pixels has a horizontal,
or x, coordinate of 0.
The x coordinate increases as you move toward the right edge
of the display, where each pixel in the rightmost column has the
value of 319 on color systems in low resolution and 639 in medium
or high resolution.
Figure 3-5. Raster Coordinate System
The ST also supports the NDC system. It's difficult to write
a single program that will work with the different types of
devices, because almost every graphics output device has a
different maximum horizontal and vertical resolution. That's where
the NDC system becomes expedient.
The NDC system offers the programmer a means by which graphics
drawn on one computer screen or printer will look the same when
drawn on other computer screens or printers of different
resolutions. With the NDC system, all graphics output is sent to
an imaginary device that is 32,768 pixels wide and 32,768 pixels
high. These pixels are grouped differently from those under the RC
system. The y axis begins with 0 at the bottom of the screen, and
moves up to the top row of pixels numbering 32,767. As in the RC
system, the x axis is numbered from left to right. The leftmost
column of pixels is 0, and the rightmost column is 32,767.
Two coordinate-referencing systems on one computer may seem
difficult to grasp, but usually you'll only be dealing with the RC
system in GFA BASIC. You should be aware of the NDC system, as it
does have value with GDOS and some VDI functions.
Figure 3-6. Normalized Device Coordinate (NDC) System
Resolving a problem
The ST may be configured in low resolution (320x200 pixels)
and medium resolution (640x200 pixels) with a color monitor, or in
high resolution (640x400 pixels) with a monochrome monitor. It's
very easy to include a simple check for the resolution mode, then
use program modules applicable for th resolution. It's even
possible to affect a change of resolution from GFA BASIC by using
an XBIOS function. At the very least, you should include a check
in your program to determine which mode of resolution the computer
is displaying. If necessary, you can then display an Alert box
informing the user that the program requires a different
resolution. Good programming practice dictates that your program
be compatible with different systems, if possible. Especially with
programs that use graphics, the effect you've labored to create
will be lost if the proper mode of resolution isn't selected.
XBIOS is a group of extended input/output functions which are
available to the programmer. For more information about XBIOS
routines, refer to Appendix F. GFA BASIC makes these functions
available to you by using the same bindings as those used by
programmers working in C. Refer to Appendix F for a list of the
XBIOS functions and bindings.
To check the resolution of a system, XBIOS 4, called getrez in
most literature about the ST, can be used.
PROCEDURE check_rez
'
rez=XBIOS(4)
'
RETURN
This procedure will return the screen resolution in the
variable, rez:
0 = low resolution (320x200, 16 colors)
1 = medium resolution (640x200, 4 colors)
2 = high resolution (640x400, monochrome)
To change resolution modes, use the following procedure. Define
rez equal to the value of the desired resolution then call
set_rez. (Note: high resolution is only available with a
monochrome monitor.)
PROCEDURE set_rez
'
dummy=XBIOS(5,L:-1,L:-1,W:rez)
'
RETURN
Switching from medium to low resolution will present no special
problems. However, when you force a switch from low resolution to
medium resolution, graphics commands will not appear on the right
side of the screen. The operating system still assumes that values
greater than 319 for X are off the screen. Meanwhile all graphics
with X coordinates less than 320, will be shown, on the left side
of the screen. Using the PRINT command to display text should
present no problem.
GFA BASIC Graphics Commands
As the following list of graphics commands illustrates, GFA
BASIC provides a powerful and easy to use programming enviornment.
More information about these commands can be found in Chapter Two,
GFA BASIC Commands and Functions or in Appendix A, Quick Reference
GFA BASIC Glossary.
BITBLT
BOX
CIRCLE
CLEARW
CLOSEW
CLS
COLOR
DEFFILL
DEFLINE
DEFMARK
DEFMOUSE
DRAW
ELLIPSE
FILL
FULLW
GET
GRAPHMODE
HARDCOPY
HIDEM
INFOW
LINE
MOUSE
MOUSEX
MOUSEY
MOUSEK
OPENW
PBOX
PCIRCLE
PELLIPSE
PRBOX
PLOT
POINT
POLYLINE
POLYFILL
POLYMARK
PUT
RBOX
SETCOLOR
SGET
SHOWM
SPRITE
SPUT
TEXT
TITLEW
VSYNC
Graphics on a 2-dimensional surface
The simplest of the graphic commands in GFA BASIC are the line
drawing commands. The simplest of these is the LINE command.
Remember, the coordinates used by the LINE command and the other
GFA BASIC graphics commands are in the Raster Coordinate (RC)
System.
Figure 3-7. Simple graphic produced by Program 3-1 using GFA
BASIC.
The following short program demonstrates the ease with which a
simple graphic screen can be developed using the LINE and BOX
commands.
GFA BASIC listings for this book have been produced by first
selecting the dir item on the Editor's menu bar, then entering,
DEFLIST 0, which causes all commands and function to be displayed
(and printed LLIST) in all capitol letters. Variable names and
names of procedures will be in lower case letters.
Program 3-1
LINEDRAW.PRG
' Simple Line Drawing Demo
'
LINE 0,100,150,100
LINE 500,100,640,100
BOX 150,50,500,150
LINE 325,25,150,50
LINE 325,25,500,50
BOX 295,80,355,150
BOX 175,90,255,130
LINE 215,90,215,130
LINE 175,110,255,110
BOX 390,90,470,130
LINE 430,90,430,130
LINE 390,110,470,110
'
In order to make the screen a little more interesting, we'll
use DEFFILL to select a pattern style and colors to be used by the
FILL command. For more information about DEFFILL, or any other GFA
BASIC command, refer to Chapter Two.
DEFFILL 3
'
FILL 5,195
'
DEFFILL 1,3
FILL 330,30
'
DEFFILL 1,2
FILL 5,5
'
DEFFILL 2,2
FILL 155,55
'
DEFFILL 2,1
FILL 310,115
The image produced will only flash on the screen, then
disappear as the edit screen reappears when the program ends . We
need to place GFA BASIC into a loop which repeats until we decide
it's time to exit the loop (and the program) and send a signal to
the interpretter. All that is needed is a REPEAT...UNTIL loop
which will wait for any key to be pressed. When a key is pressed,
the program ends.
'
REPEAT
UNTIL INKEY$<>""
END
Generally, we'll be discussing each routine used in a program,
rather than the individual commands used to obtain the desired
result. If a more detailed explanation of a command or function is
needed, refer to Chapter 2 or Appendix A.
String Art
Only a short step from line drawing is an interesting art form,
String Art. String Art may be either a succession of points
connected by lines, or a sequence of lines drawn on the screen.
Computer generated String Art may even take the form of lines
dancing around the screen, as in this program. STRING.BAS will
draw each screen and then wait for the user to press a key before
continuing. The last screen prompts the user for a positive
number. This number determines how many petals to draw on a rose.
Originally we intended this part to work only with integers,
but we discovered that some very interesting patterns develop if
you enter compound numbers (numbers with a fractional part). Try
several different values. STRING.BAS will display the rose for
each and then wait for you to press a key. If you'd like to stop
the drawing process to any time, press a key. When the drawing has
stopped, pressing a key will prompt you for a new number. Enter 0
to exit STRING.BAS. The LINE command is used to draw each of the
screens.
Program 3-2. String Art
The first thing String Art does is check the current screen
resolution and set the global variables x_size and y_size to the
width and height of the screen, respectively.
' What resolution is the ST in?
' xbios(4) returns 0 if low , 1 if medium, and 2 if high
resolution
rez=XBIOS(4)
'
' set x_size to the width and y_size to the height of the screen
'
IF rez=0
x_size=320
y_size=200
ENDIF
IF rez=1
x_size=640
y_size=200
ENDIF
IF rez=2
x_size=640
y_size=400
ENDIF
'
STRING.BAS is written so that each screen is drawn by a
separate procedure; this makes it easy to delete some of the
existing screens or add new ones of your own. After each screen is
drawn, STRING.BAS waits for any key to be pressed before it clears
the screen and draws the next screen.
GOSUB screen_1
GOSUB wait_key
CLS
GOSUB screen_4
GOSUB wait_key
CLS
GOSUB screen_2
GOSUB wait_key
CLS
GOSUB screen_3
GOSUB wait_key
CLS
GOSUB screen_5
'
END
The rest of STRING.BAS consists of the procedures used in
calculating or actually drawing the figures.
'
'
' PROCEDURE wait_key
'
' This subroutine pauses the program until the user presses a
key.
'
PROCEDURE wait_key
REPEAT
UNTIL inkey$<>""
RETURN ! end of wait_key
The following procedure converts the radius and theta values of
polar coordinates to Cartesian coordinates. See the section on
coordinate systems earlier in this chapter for details.
'
'
' PROCEDURE polar_to_rect
'
' This procedure converts from the polar coordinate system to the
' rectangular coordinate system. Pass r (radius) and theta to
' polar_to_rect and it will return the x and y values in the GLOBAL
' VARIABLES x and y.
'
PROCEDURE polar_to_rect(r,theta)
x=r*COS(theta)
y=r*SIN(theta)
RETURN ! end of polar_to_rect
This routine is used to draw two of the screens in STRING.BAS,
by calculating the values necessary for the end points of the line
to trace a limacon. Procedure limacon is used in the procedures
screen --1 and screen --2. The first parameter of limacon is the
angle theta for which the radius is to be calculated. The next two
parameters are constants which modify the shape of the limacon.
You might find it interesting to play around with these constants.
'
'
' PROCEDURE limacon
'
' This procedure returns the value of r (radius) necessary to draw
' a limacon given the angle of theta and two scaling factors, m and n.
' NOTE: r is a GLOBAL VARIABLE.
'
PROCEDURE limacon(theta,m,n)
r=m+n*COS(theta)
RETURN ! end of limacon
Procedure rose generates one of the prettiest patterns possible
using polar coordinates. Its output is used in screen 5.
'
'
' PROCEDURE rose
'
' This procedure returns the value of r (radius) necessary to
draw
' a rose given the angle theta, the number of leaves, n, and a
scaling
' factor m. n determines the number of leaves in the rose. If n is
even,
' then the rose will have 2n petals; if n is odd, there will be n
leaves.
' NOTE: r is a GLOBAL VARIABLE.
'
PROCEDURE rose(theta,n,m)
r=m*COS(n*theta)
RETURN
end of rose denominator is used in screen --5 to determine how
much of the flower to draw. The denominator returned by this
procedure is used to calculate the upper limit of the function
before it is plotted.
'
'
' PROCEDURE denominator
'
' This routine returns the denominator of a number with a
fractional component.
'
PROCEDURE denominator(num)
LOCAL k
LOCAL a
LOCAL b
'
k=1
found=0
a=num
GOSUB denom(a)
IF found=0
a=num/SQR(2)
GOSUB denom(a)
ENDIF
IF found=0
a=num/SQR(3)
GOSUB denom(a)
ENDIF
IF found=0
a=num/SQR(5)
GOSUB denom(a)
ENDIF
IF found=0
a=num/PI
GOSUB denom(a)
ENDIF
IF found=0
a=num/PI^2
GOSUB denom(a)
ENDIF
IF found=0
a=num/EXP(1)
GOSUB denom(a)
ENDIF
IF found=0
a=num*PI
k=PI
GOSUB denom(a)
ENDIF
IF found=0
a=num*PI^2
k=PI^2
GOSUB denom(a)
ENDIF
IF found=0
k=1
ENDIF
'
d=b*k
RETURN
'
'
' PROCEDURE denom
'
' This routine actually calculates the denominator of the fraction.
'
PROCEDURE denom(a)
LOCAL c
LOCAL dun
c=ABS(a)
b=1
REPEAT
dun=0
b=b/c
c=(1/c)-INT(1/c)
IF b>100000
dun=1
ENDIF
UNTIL c<1.0E-06 OR dun<>0
IF dun<>1
b=INT(b)
found=1
ENDIF
RETURN
The remaining five procedures actually draw the screens. Each
of them is well documanted in the code so we won't go into detail
on them.
'
'
' PROCEDURE screen_1
'
' This procedure draws the first screen using the procedures,
' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
'
PROCEDURE screen_1
LOCAL steps
LOCAL y_scale !y scaling factor
LOCAL x_scale !x scaling factor
LOCAL l_limit !lower limit of funtion
LOCAL u_limit !upper limit of function
LOCAL x_inc !x or theta increment
IF rez=0
steps=1000*PI
ENDIF
IF rez=1
steps=2000*PI
ENDIF
IF rez=2
steps=4000*PI
ENDIF
'
y_scale=y_size/2
l_limit=0
u_limit=2*PI
x_scale=x_size/2
x_inc=x_scale/steps
'
FOR theta=l_limit TO u_limit STEP x_inc
GOSUB limacon(theta,y_scale*3/4,y_scale*3/4)
GOSUB polar_to_rect(r,theta)
x1=x
y1=y
GOSUB limacon(theta,y_scale*3/4,-y_scale*3/4)
GOSUB polar_to_rect(r,theta)
x2=x
y2=y
IF rez<>1
LINE x1+x_scale,y1+y_scale,x2+x_scale,y2+y_scale
ELSE
LINE x1*2+x_scale,y1+y_scale,x2*2+x_scale,y2+y_scale
ENDIF
NEXT theta
RETURN ! end of screen_1
'
'
' PROCEDURE screen_2
'
' This procedure draws the second screen using the procedures,
' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
'
PROCEDURE screen_2
LOCAL steps
LOCAL y_scale !y scaling factor
LOCAL x_scale !x scaling factor
LOCAL l_limit !lower limit of funtion
LOCAL u_limit !upper limit of function
LOCAL x_inc !x or theta increment
IF rez=0
steps=250*PI
ENDIF
IF rez=1
steps=500*PI
ENDIF
IF rez=2
steps=1000*PI
ENDIF
'
y_scale=y_size/2
l_limit=0
u_limit=2*PI
x_scale=x_size/(u_limit-l_limit)
x_inc=x_scale/steps
' ferp
FOR theta=l_limit TO u_limit STEP x_inc
GOSUB limacon(theta,y_scale*9/14,y_scale)
GOSUB polar_to_rect(r,theta)
x1=x
y1=y
GOSUB limacon(theta,y_scale*9/14,-y_scale)
GOSUB polar_to_rect(r,theta)
x2=x
y2=y
IF rez<>1
LINE x2+x_size*15/16,y2+y_size/2,x1+x_size/16,y1+y_size/2
ELSE
LINE x2*2+x_size*15/16,y2+y_size/2,x1*2+x_size/16,y1+y_size/2
ENDIF
NEXT theta
RETURN ! end of screen_2
'
'
' PROCEDURE screen_3
'
' This procedure draws the third screen using the procedures,
' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
'
PROCEDURE screen_3
LOCAL steps
LOCAL y_scale !y scaling factor
LOCAL x_scale !x scaling factor
LOCAL l_limit !lower limit of funtion
LOCAL u_limit !upper limit of function
LOCAL x_inc !x or theta increment
IF rez=0
steps=500*PI
ENDIF
IF rez=1
steps=750*PI
ENDIF
IF rez=2
steps=1000*PI
ENDIF
'
y_scale=y_size/2
l_limit=0
u_limit=8*PI
x_scale=x_size/2
x_inc=x_scale/steps
'
FOR i=l_limit TO u_limit STEP x_inc
x1=SIN(i)+1
x2=SIN(i-3*PI/4)+1
y1=COS(i*3/4)+1
y2=COS((i-3*PI/4)*3/4)+1
LINE x1*x_scale,y1*y_scale,x2*x_scale,y2*y_scale
PAUSE 1
NEXT i
RETURN ! end of screen_3
'
'
' PROCEDURE screen_4
'
' This procedure draws the fourth screen using the procedures,
' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
'
PROCEDURE screen_4
LOCAL steps
LOCAL y_scale !y scaling factor
LOCAL x_scale !x scaling factor
LOCAL l_limit !lower limit of funtion
LOCAL u_limit !upper limit of function
LOCAL x_inc !x or theta increment
IF rez=0
steps=250*PI
ENDIF
IF rez=1
steps=500*PI
ENDIF
IF rez=2
steps=1000*PI
ENDIF
'
y_scale=y_size/2
l_limit=0
u_limit=5*PI
x_scale=x_size/2
x_inc=x_scale/steps
'
FOR i=l_limit TO u_limit STEP x_inc
x1=SIN(i)+1
x2=SIN(i-3*PI/4)+1
y1=COS(i*5/6)+1
y2=COS((i-3*PI/4)*5/6)+1
LINE x1*x_scale,y1*y_scale,x2*x_scale,y2*y_scale
PAUSE 1
NEXT i
RETURN ! end of screen_4
'
'
' PROCEDURE screen_5
'
' This procedure draws the fifth screen using the procedures,
' NOTE: the following variables are GLOBAL: rez, x_size, and y_size.
'
PROCEDURE screen_5
LOCAL steps
LOCAL y_scale !y scaling factor
LOCAL x_scale !x scaling factor
LOCAL l_limit !lower limit of funtion
LOCAL u_limit !upper limit of function
LOCAL x_inc !x or theta increment
IF rez=0
steps=500*PI
ENDIF
IF rez=1
steps=1000*PI
ENDIF
IF rez=2
steps=4000*PI
ENDIF
'
y_scale=y_size/2
l_limit=0
x_scale=x_size/2
'
PRINT " This routine draws flowers with the"
PRINT "number of petals that you specify."
PRINT "If you enter an odd number, n, a flower"
PRINT "with n petals will be drawn. If you"
PRINT "enter an even number, n, a flower with"
PRINT "2n petals will be drawn. Flowers with"
PRINT "large numbers of petals look like"
PRINT "filled-in circles, so keep your number"
PRINT "small. You can stop the drawing at any"
PRINT "by pressing a key. When the drawing has"
PRINT "stopped, press any key to continue."
PRINT
REPEAT
INPUT "Input a positive number (0 to quit) ";n
UNTIL n>=0
WHILE n>0
CLS
u_limit=1
d=1
IF INT(n)<>n
found=0
GOSUB denominator(n)
u_limit=d
ENDIF
IF ODD(n*d) AND ODD(d)
u_limit=PI*u_limit
ELSE
u_limit=2*PI*u_limit
ENDIF
steps=2000*PI*n
x_inc=x_scale/steps
theta=l_limit
a$=""
WHILE theta<=u_limit AND a$=""
GOSUB rose(theta,n,y_scale) ! rose returns r
GOSUB polar_to_rect(r,theta) ! polar returns x and y
x1=x
y1=y
GOSUB rose(theta-PI/(3*n),n,y_scale)
GOSUB polar_to_rect(r,theta-PI/(3*n))
IF rez=1
LINE x1*2+x_scale,y1+y_scale,x*2+x_scale,y+y_scale
ELSE
LINE x1+x_scale,y1+y_scale,x+x_scale,y+y_scale
ENDIF
theta=theta+x_inc
a$=INKEY$
WEND
GOSUB wait_key
PRINT "Previous Number = ";n;" (";n*d;"/";d;")"
REPEAT
INPUT "Input a positive integer (0 to quit) ";n
UNTIL n>=0
WEND
RETURN ! end of screen_5
Kaleidoscope
Here's a colorful demonstration program reminiscent of the Lava
Lamps popular during the 1960s. You may have seen a version of ths
program running on the Commodore Amiga, or even a C language
version on th ST. KALEDIOSCOPE.BAS runs from the GFA BASIC
interpretter. This program also demonstrates the use of some new
graphic commands. Note that "!" separates a comment from the
command on the same line. Also, the ' mark is used in lines which
contain only a comment. In this program you'll see color spelled
two ways; color and colour. Color is a GFA BASIC command which
sets the color to be used by a graphics command, and the in-line
Syntax checker will interpret it as such. Often to use a
descriptive label or variable name, it's advantageous to
deliberately mis-spell a word. Be sure to keep track of such mis-
spellings, and mis-spell the word the same way every time.
Program 3-3. KALEDIO.BAS
Begin by reserving an area of memory to hold the alternate
palette colors.
DIM palette(15),pal(15),pal2(15)
'
shape=0 ! Initial shape is a circle.
HIDEM ! Hide mouse
'
'
' Check for low resolution
'
IF XBIOS(4)<>0
alrt$="KALEIDOSCOPE only works in|Low Res (320X200 Pixels)"
ALERT 3,alrt$,1,"Oops!!",b
END
ENDIF
Next, set up an alternate color palette. Each color is
represented by three hexadecimal numbers, representing the three
color guns of an RGB (Red, Green, and Blue) monitor, ranging from
0 for a gun which is turned off, to 7 for a gun at the highest
output level. You can experiment with the numbers on the following
table to observe the effects of different numbers on the display.
(For more inforamtion about colors and the SETCOLOR command, refer
to Chapter 2.)
You can use the Control Panel desk accessory to get instant
feedback on mixing colors. When you use it to mix colors using
different levels of red, green, and blue, the panel displays these
color levels as numbers from 0 to 7. The desktop, and the COntrol
Panel, will change colors as you change the settings. It's best to
write down the numbers displayed as you proceed, as it may become
necessary to turn off your ST and reboot in order to restore a
readable screen. Use these numbers as the hexadecimal values in
the following table to install the colors in your color palette,
as demonstrated below.
'
'
' Set up color table
'
pal2(0)=&H555
pal2(1)=&H700
pal2(2)=&H60
pal2(3)=&H7
pal2(4)=&H5
pal2(5)=&H520
pal2(6)=&H50
pal2(7)=&H505
pal2(8)=&H222
pal2(9)=&H77
pal2(10)=&H55
pal2(11)=&H707
pal2(12)=&H505
pal2(13)=&H550
pal2(14)=&H770
pal2(15)=&H555
'
Now we'll display an Alert box containing the program title and
a few pieces of necessary preliminary information. Usually, you
won't want to use an Alert box for displaying anything except a
warning, but in this case very little information is required.
Notice that as you type in the text for the variable alrt$ the
screen will scroll to the left. When you move to the next line, a
dollar sign is displayed at the point where the text exceeds the
80 character screen limit. This dollar sign signifies that more
text exists on this line
.
'
' Display title box
'
alrt$=" Kaleidoscope|Left Button Restarts|Right Button
Changes Shape|Both Buttons End Program|"
ALERT 1,alrt$,1,"Okay",b
'
Since we plan to tamper with the color scheme, it would only be
polite to provide a means to reset the colors when we end our
program.
GOSUB save_palette '
' Setcolor 0,5,5,5 ! Set background to gray.
'
GOSUB set_colour ! Install new palette
'
start: ! Here's the real starting point
'
GOSUB restore_palette ! We want to restore colors for multiple runs
' otherwise print might be hard to read.
CLS
'
' Do some more start up stuff.
'
PRINT AT(1,10);
INPUT "How many pixels/step (1 to 10)";stp$
IF stp$=""
GOTO start
ENDIF
stp=VAL(stp$)
'
IF stp<1 OR stp>10 ! Check for valid range.
GOTO start
ENDIF
'
minr=stp
CLS
FOR colour=1 TO 12
DEFTEXT colour,17
GOSUB title
NEXT colour
c=0
The next few lines determine the starting point for the first
item to be drawn.
x=INT(RND(1)*320)
x1=x
y=INT(RND(1)*179)+20
y1=y
r=minr
dr=1
'
' Main program loop follows:
'
REPEAT
'
GOSUB new_x
GOSUB new_y
'
DEFFILL c
INC c
IF c>15
c=1
ENDIF
IF dr=1
INC r
ENDIF
IF dr=0
DEC r
ENDIF
IF r=20
dr=0
ENDIF
IF r=minr
dr=1
ENDIF
'
Now determine which shape, circle or square to draw; then display
that shape on the screen.
IF shape=0
PCIRCLE x,y,r
ELSE
PBOX x,y,x+r,y+r
ENDIF
'
GOSUB change_colour
'
k=MOUSEK
UNTIL k<>0
'
' Left mouse button pressed?
'
IF k=1
GOTO start
ENDIF
'
' Right Mouse button pressed?
'
IF k=2 AND shape=0
shape=1 ! Change shape to rectangle
GOTO start
ENDIF
'
IF k=2 AND shape=1
shape=0 ! Change shape to circle
GOTO start
ENDIF
'
PAUSE 35 ! System needs a sec or 2 here.
CLS
GOSUB restore_palette
SHOWM
END
'
Now we need to find a new value for x.
'
PROCEDURE new_x
'
IF x1>=319
SUB x,stp
ELSE
ADD x,stp
ENDIF
ADD x1,stp
IF x1>=643
x1=stp
x=stp
ENDIF
RETURN
'
Next we need a new y value.
'
PROCEDURE new_y
'
IF y1>199
SUB y,stp
ELSE
ADD y,stp
ENDIF
ADD y1,stp
IF y1>375
y1=28
y=28
ENDIF
RETURN
'
The following procedure is a useful routine you'll see often in
this book. It saves the palette as set up by the user from the
Control Panel, so that the default colors may be restored when the
program ends.
' Save Original Color Palette
'
PROCEDURE save_palette
LOCAL i
'
FOR i=0 TO 15
palette(i)=XBIOS(7,W:i,W:-1)
pal(i)=palette(i)
NEXT i
'
RETURN
'
'
Here's the procedure which restores the default color palette.
You'll see this one used again, too.
'
' Restore Original Color Palette
'
PROCEDURE restore_palette
LOCAL i
'
FOR i=0 TO 15
SETCOLOR i,palette(i)
NEXT i
RETURN
'
To give the illusion of constant movement on the screen,
we're going to rotate the color palette. This procedure takes care
of the rotation sequence.
PROCEDURE change_colour
'
temp=pal(1)
FOR i=2 TO 15
pal(i-1)=pal(i)
NEXT i
pal(15)=temp
'
FOR i=1 TO 15
SETCOLOR i,pal(i)
NEXT i
FOR i=0 TO 15
pal(i)=XBIOS(7,W:i,W:-1)
NEXT i
RETURN
'
Here is another routine to dazzle the beholder. This procedure
sets up the title "Kaleidoscope" to alternate colors with color
cycling.
PROCEDURE title
IF colour=1
TEXT 95,7,"K"
ENDIF
IF colour=2
TEXT 105,7,"a"
ENDIF
IF colour=3
TEXT 115,7,"l"
ENDIF
IF colour=4
TEXT 125,7,"e"
ENDIF
IF colour=5
TEXT 135,7,"i"
ENDIF
IF colour=6
TEXT 145,7,"d"
ENDIF
IF colour=7
TEXT 155,7,"o"
ENDIF
IF colour=8
TEXT 165,7,"s"
ENDIF
IF colour=9
TEXT 175,7,"c"
ENDIF
IF colour=10
TEXT 185,7,"o"
ENDIF
IF colour=11
TEXT 195,7,"p"
ENDIF
IF colour=12
TEXT 205,7,"e"
ENDIF
RETURN
'
The set_color procedure is used to install our custom palette
when the program intializes.
PROCEDURE set_colour
FOR i=0 TO 15
dummy=XBIOS(7,pal2(i))
NEXT i
RETURN
The Dragon Plot
Fractals have been receiving a great deal of attention in
mathematics and computer graphics. They're being used for
everything from simulating random plant growth to generating
realistic planetary landscapes in science fiction films.
Understanding fractals may not be as exciting as seeing them
in action, but some explanation should prove helpful to your
programming. The word fractal Çwas coined by Benoit Mandelbrot, a
pioneer in their study, to denote curves or surfaces having
fractional dimension. The idea of fractional dimension can be
illustrated as a straight curve (a line) which has only one-
dimension, length. If the curve is infinitely long and curves in
such a manner that it completely fills an area of the plane
containing it, the curve can be considered two-dimensional. A
curve partially filling an area has a fractional dimension between
1 and 2.
Many types of fractals are self-similar. This means that all
portions of the fractal resemble each other. This occurs whenever
the whole is an expansion of some basic building block. In the
language of fractals, this basic building block is called the
generator.
The generator in the next program consists of a number of
connected line segments.The curves plotted by this program are the
result of starting with the generator and then repeatedly
replacing each line segment, according to a defined rule. The
number of cycles is limited by the screen resolution. Select too
high a number of cycles, and the program will also slow down to a
crawl. Eventually, the screen will be filled by the fractal
generator, as portions are plotted off the screen as well.
This simple program which begins our exploration of the world of
fractals plots a particular type of fractal which Mandelbrot
labeled a "dragon plot." This program illustrates a self-
contacting curve. A self-contacting curve touches, but does not
cross, itself. The generator consists of two-line segments of
equal length forming a right angle. During each cycle, the
generator is substituted for each segment on alternating sides of
the segments. (Even though GFA BASIC executes faster than most
interpreted languages, it's still slow, and that's part of the
fascination of the dragon plot --watching as your ST plots the
figure, and noting the areas of similarity.
DRAGON.BAS begins by asking you to enter an even number of
cycles. When a plot is complete, pressing any key clears the
screen and returns you to the starting prompt. Try starting out
with two cycles, then four, then six, and so on. As you add more
cycles, more time is required to fill in the dragon.
Program 3-4. DRAGON.BAS
DIM sn(20)
in:
CLS
PRINT "Enter an even number of cycles (2-20)"
INPUT "or enter a zero to quit: ";nc$
nc=VAL(nc$)
IF nc=0
END
ENDIF
IF nc<2 OR nc>20
GOTO in
ENDIF
IF EVEN(nc)<>-1
GOTO in
ENDIF
l=128
FOR c=2 TO nc STEP 2
l=l/2
NEXT c
x=85
y=100
CLS
COLOR 3
PLOT x,y
FOR c=0 TO nc
sn(c)=0
NEXT c
rot_seg:
d=0
FOR c=1 TO nc
IF sn(c-1)=sn(c)
d=d-1
GOTO rotate_it
ENDIF
d=d+1
rotate_it:
IF d=-1
d=7
ENDIF
IF d=8
d=0
ENDIF
NEXT c
IF d=0
x=x+l+l
GOTO seg
ENDIF
IF d=2
y=y+l
GOTO seg
ENDIF
IF d=4
x=x-l-l
GOTO seg
ENDIF
y=y-l
seg:
COLOR 3
DRAW TO x,y
sn(nc)=sn(nc)+1
FOR c=nc TO 1 STEP -1
IF sn(c)<>2
c=1
GOTO next_seg
ENDIF
sn(c)=0
sn(c-1)=sn(c-1)+1
next_seg:
NEXT c
IF sn(0)=0
GOTO rot_seg
ENDIF
PRINT AT(7,23);"Press any key to continue"
REPEAT
UNTIL INKEY$<>""
GOTO in
The Mandelbrot Set
You can see fractals in nature in many places. The clouds,
coastlines displayed in satellite photographs, and even a leaf
will reveal fractals. We've seen one form of computer-generated
fractals in Program 3-5, the dragon sweep. Now we'll explore one
of the strangest and most beautiful areas of fractal geometry, the
Mandelbrot set.
The Mandelbrot set consists of complex numbers, numbers with a
"real" and "imaginary" part. These terms, real and imaginary, have
historical significance in mathematics, but are no longer
relevant. A complex number takes the form of 6 + 3i; 6 is the real
part of the number, and 3i represents the imaginary part (hence
the i). Each complex number can be represented by a point on the
two-dimensional plane.
The Mandelbrot set is located at the center of a two-
dimensional sheet of numbers called the complex plane. When a
specific operation is applied repeatedly to the numbers, the
numbers outside the set retreat to infinity. The remaining numbers
move about within the plane. Near the edge of the set, the numbers
move about in a pattern which marks the beginning of the area of
instability. This area is astonishingly beautiful, complex,
infinitely variable, and yet somehow, strangely similiar.
The unique factor in numbers within the Mandelbrot set is that
values in the set never grow larger than 2 as the mathematical
operation is performed on them. Points within the Mandelbrot set
are represented in our program by black pixels. The colors of the
other points are determined by counting the number of times each
complex number is operated on before its value exceeds 2. This
count is converted into a color.
For more information on the theory of fractals, see The Fractal
Geometry of Nature, by Benoit Mandelbrot.
Figure 3-8. The Mandelbrot Primitive
Figure 3-8 shows a representation of the entire Mandelbrot set.
You can reproduce this figure by running MANDELBROT.BAS, and
selecting 100 iterations, an X Center of .75, and a Y Center of 0.
Choose a range of 2 for viewing the complete image. Once you've
become somewhat familiar with the general coordinates of the
Mandelbrot set, try exploring the boundary area by selecting x and
y coordinates located on the boundary, and then selecting smaller
values for the range. Program 3-5, MANDELBROT.BAS, was used to
generate the image displayed in Figures 3-8, 3-9, and 3-10. Only a
black-and-white representation was possible in the book, but the
set generated by Program 3-5 is quite colorful. Some other
interesting areas to explore follow.
Figure 3-9. Mandelbrot Figure
Figure 3-10. Another Segment of the Mandelbrot Boundary.
X-Center Y-Center Range
-1 0.32 0.3
-1 0.2895 0.0005
-0.97 0.276 0.0001
In this program, we'll be introducing several new procedures
which can be used in your own programs. We'll show you later how
to merge these procedures into your programs.
Program 3-5. MANDELBROT.BAS
DIM palette(15),pal2(15)
The mouse pointer will be in the way on the picture, so we'll
just turn it off.
'
HIDEM
'
We'll check to see which resolution is in use, then give a
warning if the machine isn't in low resolution. This program will
work in any resolution; it just looks best with 16 colors, so
we'll allow it to continue if the user doesn't want to quit.
'
rez=XBIOS(4)
IF rez<>0
alrt$="Fractals look best in|Low Resolution"
ALERT 1,alrt$,1,"Continue|Quit",b
IF b=2
END
ENDIF
ENDIF
'
Next we'll establish default values for different screen
resolutions.
IF rez=0
screen_height=200 ! Low res screen
screen_width=320
ENDIF
'
IF rez=1 ! Medium resolution screen
screen_height=200
screen_width=640
ENDIF
'
IF rez=2 ! High resolution screen
screen_height=400
screen_width=640
ENDIF
'
' Main Loop begins here
'
We've used this routine before. It saves the palette so you can
restore the original colors later. It's a good programming
practice to clean up after yourself. If you change the palette,
then exit to the GFA BASIC editor, you may find yourself stuck on
a screen that is impossible to read.
GOSUB save_palette
'
Here's the main loop which controls the program.
DO
'
GOSUB values
IF rez=0
GOSUB set_new_colors
ENDIF
GOSUB calculate
IF rez=0
GOSUB restore_palette
ENDIF
GOSUB display_it
'
LOOP
We'll put an END in here, but the program never really exits
from the DO...LOOP. Other procedures are called and executed from
procedures called by the DO...LOOP, but everything within this
program actually occurs within this loop.
'
END
'
display_it is a procedure which displays information about the
calculations for this particular portion of the Mandelbrot set and
offers some options which may be selected by pressing a key.
Usually this procedure will be encountered after the calculations
for displaying the fractal are complete.
PROCEDURE display_it
'
display:
CLS
PRINT AT(1,3);"Fractal Image"
PRINT AT(1,5);count;" Iterations Calculated."
seconds=INT((time_finish-time_start)/2)/100
min=INT(seconds/60)
IF min<=0
min=0
ENDIF
seconds=ABS(INT((seconds MOD 60)*100)/100)
PRINT AT(1,7);min;" Minutes and ";seconds;" Seconds required."
PRINT AT(1,8);"Number of iterations: ";iteration_limit
PRINT AT(1,10);"X Center: ";x_center
PRINT AT(1,11);"Y Center: ";y_center
PRINT AT(1,12);"Scaling factor: ";range
PRINT AT(1,14);"Minimum real value (xmin): ";real_min
PRINT AT(1,15);"Maximum real value (xmax): ";real_max
PRINT AT(1,16);"Minimum imaginary value (ymin): ";imag_min
PRINT AT(1,17);"Maximum Imaginary value (ymax): ";imag_max
PRINT AT(1,19);"Press:"
PRINT AT(5,20);"<V> to View Fractal"
PRINT AT(5,21);"<P> to Plot new Fractal"
PRINT AT(5,22);"<S> to Save .NEO file"
PRINT AT(5,23);"<Q> to Quit"
'
key waits for the user to press a key. Then the key value is
stored in a$, and evaluated, and the proper branch is taken. UPPER
is a GFA BASIC command which converts any value in a$ to
uppercase. For more information about any GFA BASIC commands,
refer to Chapter 2.
key:
REPEAT
a$=INKEY$
UNTIL a$<>""
'
IF UPPER$(a$)="V"
SGET screen2$
IF rez=0
GOSUB set_new_colors
ENDIF
SPUT screen1$
REPEAT
UNTIL INKEY$<>""
GOSUB restore_palette
SPUT screen2$
ENDIF
'
IF UPPER$(a$)="P"
GOTO finito
ENDIF
'
IF UPPER$(a$)="Q"
SHOWM
CLS
END
ENDIF
'
IF UPPER$(a$)="S"
'
Here's a handy procedure that saves the screen into a
NEOchrome-compatible file. Following this program, we'll give you
a simple routine which can be merged with your programs, and show
you how you can use this routine to load screens in your own
programs.
IF rez<>0
CLS
ALRT$="Must be Low Res|for Neochrome files"
ALERT 1,alrt$,1,"OKAY",b
ENDIF
GOTO not_neo
'
SGET screen2$
default$="C:\*.NEO"
FILESELECT default$,"",infile$
CLS
IF infile$="" !equals "" if CANCEL selected
GOTO not_neo
ENDIF
GOSUB set_new_colors
SPUT screen1$
OPEN "o",#1,infile$
'
' First two bytes to zero
'
FOR i=0 TO 2
OUT #1,0
OUT #1,0
NEXT i
'
' Save color palette
'
FOR i=0 TO 15
hi=INT(pal2(i)/256)
lo=pal2(i)-256*hi
OUT #1,hi
OUT #1,lo
NEXT i
'
' Color cycling info (not needed)
'
FOR i=0 TO 89
OUT #1,0
NEXT i
'
' Save screen info
'
BPUT #1,XBIOS(3),32000
'
CLOSE
SPUT screen2$
GOSUB restore_palette
'
not_neo:
'
ENDIF
'
GOTO display
'
finito:
'
RETURN
'
values accepts input from the user for the values to be
examined for the Mandelbrot boundaries.
PROCEDURE values
'
CLS
INPUT "Number of iterations";iteration_limit
INPUT "Center X";x_center
INPUT "Center Y";y_center
INPUT "Scale Range";range
real_min=x_center-(range/2)
real_max=x_center+(range/2)
imag_max=y_center+((range/2)*0.77)
imag_min=y_center-((range/2)*0.77)
CLS
RETURN
'
The next procedure does the real work. The complex number is
evaluated as defined. Several arbitary values were selected for
constants. You may find it interesting to change values, such as
max_limit, to observe any changes in the figure plotted.
time_start is used to calculate the time it took to complete the
plot.
Note that even though GFA BASIC is one of the fastest
interpreters available, fractals can take a lot of time to plot.
Most designs will take over an hour to complete. The closer the
complex numbers are to the Mandelbrot set, the more calculations
are required before the result exceeds 2. Therefore, more time is
required.
PROCEDURE calculate
'
time_start=INT(TIMER)
max_limit=100000000
count=0
real=(real_max-real_min)/(screen_width-1)
imaginary=(imag_max-imag_min)/(screen_height-1)
FOR y=0 TO screen_height
FOR x=0 TO screen_width
lreal=real_min+x*real
limag=imag_min+y*imaginary
re=lreal
im=limag
depth=0
calc_loop:
INC count
x1=re^2
y1=im^2
im=2*re*im-limag
re=x1-y1-lreal
INC depth
IF ((depth=iteration_limit) OR ((x1+y1)>max_limit))
GOTO finished_yet
ELSE
GOTO calc_loop
ENDIF
finished_yet:
IF (depth<iteration_limit)
GOSUB draw_point
ENDIF
Since we can get stuck here waiting on the calculations for a
long time, this will offer a way out and allow us a means to check
on the time spent and calculations completed on this particular
set of complex numbers.
IF INKEY$<>""
GOSUB break
ENDIF
NEXT x
NEXT y
'
' Save screen into screen1$
'
SGET screen1$
'
time_finish=INT(TIMER) ! time of completion
'
RETURN
'
If a key is pressed, we must stop to evaluate it. We'll also
display an interim screen with some interesting information.
PROCEDURE break
'
SGET screen1$
time_finish=INT(TIMER)
IF rez=0
GOSUB restore_palette
ENDIF
CLS
PRINT AT(1,3);"Fractal Image"
PRINT AT(1,5);count;" Iterations Calculated."
seconds=INT((time_finish-time_start)/2)/100
min=INT(seconds/60)
IF min<=0
min=0
ENDIF
seconds=ABS(INT((seconds MOD 60)*100)/100)
PRINT AT(1,7);min;" Minutes and ";seconds;" Seconds required."
PRINT AT(1,8);"Number of iterations: ";iteration_limit
PRINT AT(1,10);"X Center: ";x_center
PRINT AT(1,11);"Y Center: ";y_center
PRINT AT(1,12);"Scaling factor: ";range
PRINT AT(1,14);"Minimum real value (xmin): ";real_min
PRINT AT(1,15);"Maximum real value (xmax): ";real_max
PRINT AT(1,16);"Minimum imaginary value (ymin): ";imag_min
PRINT AT(1,17);"Maximum Imaginary value (ymax): ";imag_max
PRINT AT(1,19);"Press:"
PRINT AT(5,20);"<C> to Continue Plot"
PRINT AT(5,21);"<E> to Return to Main Menu"
'
keyit:
REPEAT
a$=INKEY$
UNTIL a$<>""
'
IF UPPER$(a$)="E"
x=screen_width
y=screen_height
SPUT screen1$
GOTO finit
ENDIF
'
IF UPPER$(a$)="C"
IF rez=0
GOSUB set_new_colors
ENDIF
SPUT screen1$
GOTO finit
ENDIF
'
GOTO keyit
'
finit:
RETURN
The calculations are completed; now it's time to plot the
point. Depth is equal to the number of iterations calculated on
the number which represents the point.
'
PROCEDURE draw_point
'
colour=depth MOD 16
COLOR colour
IF (depth>100)
PLOT x,y
ELSE
GOSUB greater_than_two
ENDIF
RETURN
'
PROCEDURE greater_than_two
'
IF depth MOD 2
PLOT x,y
ENDIF
RETURN
'
set_new_colors changes the color palette by installing the
colors we've selected into the hardware register for the palette.
PROCEDURE set_new_colors
'
' Set up color table
'
pal2(0)=&H0
pal2(1)=&H75
pal2(2)=&H765
pal2(3)=&H401
pal2(4)=&H410
pal2(5)=&H530
pal2(6)=&H241
pal2(7)=&H62
pal2(8)=&H474
pal2(9)=&H744
pal2(10)=&H731
pal2(11)=&H165
pal2(12)=&H14
pal2(13)=&H750
pal2(14)=&H423
pal2(15)=&H601
'
'
FOR i=0 TO 15
SETCOLOR i,pal2(i)
NEXT i
RETURN
'
We've seen the next two procedures before.
'
' Save Original Color Palette
'
PROCEDURE save_palette
LOCAL i
'
'
FOR i=0 TO 15
palette(i)=XBIOS(7,W:i,W:-1)
NEXT i
RETURN
'
'
'
' Restore Original Color Palette
'
PROCEDURE restore_palette
LOCAL i
'
FOR i=0 TO 15
SETCOLOR i,palette(i)
NEXT i
RETURN
Saving a Screen in NEOchrome Format
Here's a simple little routine similar to the one used in
MANDELBROT.BAS. This program can easily be merged with any of your
programs.
Program 3-6. NEOWRITE.BAS
Procedure Save_neoscreen
'Reserve an area of memory for the alternate palette.
'
Dim Pal2(15)
'
Gosub Save_palette
Hidem
'
Sget Screen1$
'
Rez=Xbios(4)
If Rez<>0
Cls
Print ''Must be Low Resolution for Neochrome''
Repeat
Until Inkey$<>''''
Cls
Sput Screen1$
Goto Not_neo
Endif
'
Default$=''A:\*.NEO''
Fileselect Default$,'''',Infile$
Cls
Sput Screen1$
Open ''o'',#1,Infile$
'
' First three words to zero
'
For I=0 To 2
Out #1,0
Out #1,0
Next I
'
' Save color palette
'
For I=0 To 15
Hi=Int(Pal2(I)/256)
Lo=Pal2(I)-256*Hi
Out #1,Hi
Out #1,Lo
Next I
'
' Color cycling info (not needed)
'
For I=0 To 89
Out #1,0
Next I
'
' Save screen info
'
Bput #1,Xbios(3),32000
'
Close
'
Not_neo:
'
Endif
'
'
Finito:
'
Return
'
' Save Original Color Palette
'
Procedure Save_palette
Local I
'
'
'
For I=0 To 15
Pal2(I)=Xbios(7,W:I,W:-1)
Next I
Return
'
After you've saved a screen in a NEOchrome format, you'll need a
routine to display the screen without loading NEOCHROME.PRG.
Here's a routine to load any NEOchrome-format screen. With a minor
alteration, you may load any screen into your programs without
using the fileselector box.
Program 3-7. NEOLOAD.BAS
DIM palette(15),pal2(15)
'
GOSUB save_palette
'
Here's the main loop. Use these procedures as applicable in
your program to load .NEO files. Refer to the user's guide for
DEGAS Elite for information on how to handle a DEGAS file. It's
just as simple.
main:
'
GOSUB check_rez
GOSUB choose_pic
HIDEM
GOSUB load_colour
GOSUB install_colour
GOSUB show_pic
'
g$=''''
REPEAT
g$=INKEY$
UNTIL g$<>''''
'
CLS
'
GOSUB restore_palette
'
IF UPPER$(g$)=''Q''
END
ENDIF
'
SHOWM
GOTO main
'
'
PROCEDURE check_rez
'
rez=XBIOS(4)
IF rez<>0
alrt$=''NEOLOAD only works in|Low Resolution.''
ALERT 3,alrt$,1,''Exit'',b
END
ENDIF
'
RETURN
'
PROCEDURE choose_pic
'
The next section was included to allow you to select a
NEOchrome-format file using the standard GEM file selector. If
you'd like to load a predetermined file, omit this procedure and
define Filename$ as the name of the desired program before calling
Procedure Load_colour.
'
disk$=''*.NEO''
FILESELECT disk$,'''',filename$
IF filename$=''''
END
ENDIF
'
RETURN
'
PROCEDURE load_colour
'
OPEN ''I'',#1,filename$
temp$=INPUT$(38,#1)
The first six bytes of the file don't matter, so we'll strip them
off.
colour$=MID$(temp$,7,32)
CLOSE #1
'
Next, we'll break down the two-byte color values into values which
we can assign to our alternate palette, and install the colors.
palnum=0
count=0
REPEAT
hibyte=ASC(MID$(colour$,count,1))
INC count
lobyte=ASC(MID$(colour$,count,1))
INC count
pal2(palnum)=(hibyte*256)+lobyte
INC palnum
UNTIL palnum=15
'
RETURN
'
The following XBIOS routine changes the hardware pointer to the
palette to point to the variable Colour$. Changing this pointer
installs the new palette.
PROCEDURE install_colour
'
VOID XBIOS(6,L:VARPTR(colour$))
'
RETURN
'
Here's a little trick for loading the picture. XBIOS (2) is an
XBIOS function which returns the location of the physical screen.
This will vary for 520s and 1040s. Actually, we're cheating a bit
here. We know that the first 128 bytes of a NEOchrome file contain
information we're not interested in (information concerning the
resolution, which is never used, the color palette, and the color
rotation ). What we'll do is ignore this information and begin
loading the picture into an absolute memory location 128 bytes
lower than the beginning of screen memory. This area isn't usually
used for anything, and provides an easy way to strip off the
unneeded bytes and load the picture image.
PROCEDURE show_pic
'
physbase=XBIOS(2)
BLOAD filename$,physbase-128
'
RETURN
'
' Save Original Color Palette
'
PROCEDURE save_palette
'
FOR i=0 TO 15
palette(i)=XBIOS(7,W:i,W:-1)
NEXT i
'
RETURN
'
PROCEDURE restore_palette
'
FOR i=0 TO 15
SETCOLOR i,palette(i)
NEXT i
'
RETURN
Great Graphics
As you have seen from these simple examples, GFA BASIC makes
graphics programming easy. It's not necessary to resort to PEEK's
and POKE's to achieve the spectacular. This is only the starting
point. As you continue to explore graphics with GFA BASIC, you'll
be amazed at the power you can unleash as use the power of the
68000 Microprocessor.
In the next chapter, we'll introduce you to an even more
impressive use of graphics -- Animation. Soon you'll be writing
the games you dream about.
⇦e you to an even more
impressive use of graphics -- Ani